/************************************************
 * Author       :   XXY
 * Blog         :   https://www.cnblogs.com/jzyl
 * Gitee        :   https://gitee.com/xiaobaichong
 * Email        :   1047185209@QQ.com
 * FileName     :   WebUtility.cs
 * CreateData   :   2023/5/17 17:31:04
 * UnityVersion :   2021.3.20f1c1
 * Description  :   网络工具
************************************************/

using Cysharp.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Sirenix.Serialization;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;

#pragma warning disable CS0168
namespace Main
{
    /// <summary>
    /// 网络工具
    /// </summary>
    public static class WebUtility
    {
        public static bool IsUrl(string str)// 是否是有效链接
        {
            try
            {
                string Url = @"^http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?$";
                return Regex.IsMatch(str, Url);
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        /// <summary>
        /// 获取网络状态
        /// <para>etworkReachability.NotReachable：设备未连接到互联网。</para>
        /// <para>NetworkReachability.ReachableViaCarrierDataNetwork：设备通过移动数据连接（例如 3G、4G 或 5G）连接到互联网。</para>
        /// <para>NetworkReachability.ReachableViaLocalAreaNetwork：设备通过 Wi-Fi 或有线网络连接到互联网。</para>
        /// </summary>
        /// <returns></returns>
        public static NetworkReachability WebState()
        {
            return Application.internetReachability;
        }
        public static WebClient CreateWeb()
        {
            return new WebClient();
        }
        public static string GetWebString(string url)
        {
            WebClient web = CreateWeb();
            try
            {
                string value = web.DownloadString(url);
                return value;
            }
            catch(Exception ex)
            {
                Debug.LogError(ex.ToString());
                throw new Exception(ex.ToString());
            }
        }
        public async static Task<string> GetWebString(string url, Action<string> Completed=null)
        {
            WebClient web = CreateWeb();
            string value = await web.DownloadStringTaskAsync(url);
            Completed?.Invoke(value);
            return value;
        }
        public async static void GetWebBytes(string url, Action<Byte[]> Completed)
        {
            WebClient web = CreateWeb();
            Byte[] value = await web.DownloadDataTaskAsync(url);
            Completed?.Invoke(value);
        }
        public async static void GetWebFile(string url, string filePath, Action Completed, DownloadProgressChangedEventHandler DownloadProgressCallback)
        {
            WebClient web = CreateWeb();
            web.DownloadProgressChanged += DownloadProgressCallback;
            await web.DownloadFileTaskAsync(url, filePath);
            Completed?.Invoke();
        }
        public async static void PostWebString(string url, string data, Action<string> Completed)
        {
            WebClient web = CreateWeb();
            string value = await web.UploadStringTaskAsync(url, data);
            Completed?.Invoke(value);
        }
        public async static void PostWebBytes(string url, byte[] data, Action<byte[]> Completed)
        {
            WebClient web = CreateWeb();
            byte[] value = await web.UploadDataTaskAsync(url, data);
            Completed?.Invoke(value);
        }
        public async static void PostWebFile(string url, string filePath, Action<byte[]> Completed)
        {
            WebClient web = CreateWeb();
            byte[] value = await web.UploadFileTaskAsync(url, filePath);
            Completed?.Invoke(value);
        }
        public async static void PostWebValues(string url, NameValueCollection data, Action<byte[]> Completed)
        {
            WebClient web = CreateWeb();
            byte[] value = await web.UploadValuesTaskAsync(url, data);
            Completed?.Invoke(value);
        }

        /// <summary>
        /// Web 请求方法
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="method">方法（"CREATE","DELETE","GET","HEAD","POST","PUT"）</param>
        /// <param name="body">请求体</param>
        /// <param name="headers">请求头</param>
        public async static UniTask<DownloadHandler> WebRequest(string url, string method, JObject body = null, Dictionary<string, string> headers = null)
        {
            DownloadHandler downloadHandler = new DownloadHandlerBuffer();
            UploadHandler uploadHandler = body != null ? new UploadHandlerRaw(Encoding.UTF8.GetBytes(body.ToString())) : null;

            UnityWebRequest request = new UnityWebRequest(url, method, downloadHandler, uploadHandler);
            if (headers != null)
            {
                foreach (var item in headers)
                {
                    request.SetRequestHeader(item.Key, item.Value);
                }
            }
            await request.SendWebRequest();
            if (request.result == UnityWebRequest.Result.Success)
            {
                return request.downloadHandler;
            }
            else
            {
                throw new Exception(request.error);
            }
        }
    }
}
